/*
Author : Nguyen Van Ty
Email  : ngvanty03@gmail.com
Date   : 12/26/2010 

*/

using System;
using System.Collections.Generic;
using System.Text;
using log4net;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Utility;
using BusinessObject;
using System.Xml;

namespace DataAccessLayer
{
    /// <summary>
    /// Define PhieuBanHangDao class. This class inherit from  PhieuBanHangDaoBase class.
    /// If you want add new function, you must define here.
    /// </summary>
    public class PhieuBanHangDao : PhieuBanHangDaoBase
    {
        private static ILog logger = null;
        #region Constructor
        /// <summary>
        /// Define Constructor.
        /// </summary>
        public PhieuBanHangDao() { }
        static PhieuBanHangDao()
        {
            // Init logger.
            logger = LoggingUtility.GetLogger(typeof(PhieuBanHangDao).FullName);
        }
        public static Int64 Insert(PhieuBanHang obj, KhachHang objKhachHang, List<ChiTietPhieuBanHang> lstChiTiet)
        {
            Int64 id = 0;
            String methodName = "InsertPhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            ManagerDao.BeginTransaction();
            //insert Khach hang
            int maKH = KhachHangDao.Insert(objKhachHang);
            if (maKH <= 0)
            {
                ManagerDao.Rollback();
                return 0;
            }
            DbCommand cmd = ManagerDao.GetStoredProcCommand("spInsertPhieuBanHang");

            //Add value "NgayBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayBan", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.NgayBan));
            //Add value "NguoiBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiBan", DbType.String,
                ConvertValueObject.CastObjValueToInsertDB(obj.NguoiBan));
            //Add value "TongGiaTien"  paramater.
            ManagerDao.AddInParameter(cmd, "TongGiaTien", DbType.Double,
                ConvertValueObject.CastObjValueToInsertDB(obj.TongGiaTien));
            //Add value "MaKho"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKho", DbType.Int32,
                ConvertValueObject.CastObjValueToInsertDB(obj.MaKho));
            //Add value "MaKhachHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKhachHang", DbType.Int32,
                ConvertValueObject.CastObjValueToInsertDB(maKH));
            //Add value "NguoiLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiLapPhieu", DbType.String,
                ConvertValueObject.CastObjValueToInsertDB(obj.NguoiLapPhieu));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayLapPhieu", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.NgayLapPhieu));
            //////////////////////
            ManagerDao.AddInParameter(cmd, "SysCreatedBy", DbType.String,
               ConvertValueObject.CastObjValueToInsertDB(obj.SysCreatedBy));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "SysCreatedDate", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.SysCreatedDate));
            //////////////////////
            ManagerDao.AddInParameter(cmd, "SysUpdatedBy", DbType.String,
               ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedBy));
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedDate", DbType.DateTime,
                ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedDate));


            //add paramater store return value.        
            ManagerDao.AddParameter(cmd, "returnValue", DbType.Int64, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {
                ManagerDao.ExecuteNonQuery(cmd);
                id = Int64.Parse(ManagerDao.GetParameterValue(cmd, "returnValue").ToString());
                if (id > 0)//Successfull.
                {
                    //insert list Detail
                    if (lstChiTiet != null && lstChiTiet.Count > 0)
                    {
                        foreach (ChiTietPhieuBanHang objChiTiet in lstChiTiet)
                        {
                            //kiem tra so luong nhap nho hon so luong ton
                            int soLuongTon = MatHangDao.GetSoLuongTonByDonViTinh(objChiTiet.MaMatHang, obj.MaKho, objChiTiet.MaDonViTinh);
                            if (soLuongTon < objChiTiet.SoLuong)
                            {
                                ManagerDao.Rollback();
                                return 0;
                            }
                            objChiTiet.MaPhieuBanHang = id;
                            if (!ChiTietPhieuBanHangDao.Insert(objChiTiet))
                            {
                                ManagerDao.Rollback();
                                return 0;
                            }
                            //Update MatHangTonKho
                            MatHangTonKho objTonKho = new MatHangTonKho();
                            objTonKho.MaDonViTinh = objChiTiet.MaDonViTinh;
                            objTonKho.MaKho = obj.MaKho;
                            objTonKho.MaMatHang = objChiTiet.MaMatHang;
                            objTonKho.SoLuongTon = objChiTiet.SoLuong;
                            if (!MatHangTonKhoDao.RemoveMatHangTonKho(objTonKho))
                            {
                                ManagerDao.Rollback();
                                return 0;
                            }
                        }
                        ManagerDao.Commit();
                        return id;
                    }
                }
            }
            catch (Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            ManagerDao.Rollback();
            return 0;
        }
        public static bool Update(PhieuBanHang obj, KhachHang objKhachHang, List<ChiTietPhieuBanHang> lstChiTiet)
        {
            
            String methodName = "UpdatePhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            List<ChiTietPhieuBanHangResult> lstChiTietOld = ChiTietPhieuBanHangDao.GetByMaPhieuBanHang(obj.MaPhieuBanHang);

            ManagerDao.BeginTransaction();

            DbCommand cmd = ManagerDao.GetStoredProcCommand("spUpdatePhieuBanHang");
            //Add value "MaPhieuBanHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaPhieuBanHang", DbType.Int64, obj.MaPhieuBanHang);
            //Add value "NgayBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayBan", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.NgayBan));
            //Add value "NguoiBan"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiBan", DbType.String, ConvertValueObject.CastObjValueToInsertDB(obj.NguoiBan));
            //Add value "TongGiaTien"  paramater.
            ManagerDao.AddInParameter(cmd, "TongGiaTien", DbType.Double, obj.TongGiaTien);
            //Add value "MaKho"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKho", DbType.Int32, obj.MaKho);
            //Add value "MaKhachHang"  paramater.
            ManagerDao.AddInParameter(cmd, "MaKhachHang", DbType.Int32, obj.MaKhachHang);
            //Add value "NguoiLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NguoiLapPhieu", DbType.String, obj.NguoiLapPhieu);
            //Add value "NgayLapPhieu"  paramater.
            ManagerDao.AddInParameter(cmd, "NgayLapPhieu", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.NgayLapPhieu));

            //Add value "SysUpdatedBy"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedBy", DbType.String, obj.SysUpdatedBy);
            //Add value "SysUpdatedDate"  paramater.
            ManagerDao.AddInParameter(cmd, "SysUpdatedDate", DbType.DateTime, ConvertValueObject.CastObjValueToInsertDB(obj.SysUpdatedDate));

            // add parameter store return value.
            ManagerDao.AddParameter(cmd, "returnValue", DbType.Int32, ParameterDirection.ReturnValue, string.Empty, DataRowVersion.Default, null);
            try
            {
                ManagerDao.ExecuteNonQuery(cmd);
                int rows = (int)ManagerDao.GetParameterValue(cmd, "returnValue");
                if (rows >= 1)//Successfull.
                {
                    //rollback old data
                    foreach (ChiTietPhieuBanHangResult objOldDetail in lstChiTietOld)
                    {
                        //Update MatHangTonKho
                        MatHangTonKho objTonKho = new MatHangTonKho();
                        objTonKho.MaDonViTinh = objOldDetail.MaDonViTinh;
                        objTonKho.MaKho = obj.MaKho;
                        objTonKho.MaMatHang = objOldDetail.MaMatHang;
                        objTonKho.SoLuongTon = objOldDetail.SoLuong;
                        if (!MatHangTonKhoDao.RollBackMatHangTonKho(objTonKho))
                        {
                            ManagerDao.Rollback();
                            return false;
                        }
                    }
                    //delete old data
                    if (!ChiTietPhieuBanHangDao.DeleteByMaPhieuBan(obj.MaPhieuBanHang))
                    {
                        ManagerDao.Rollback();
                        return false;
                    }
                    //uPDATE KhachHang
                    if (!KhachHangDao.Update(objKhachHang))
                    {
                        ManagerDao.Rollback();
                        return false;
                    }
                    //reinsert new data
                    if (lstChiTiet != null && lstChiTiet.Count > 0)
                    {
                        foreach (ChiTietPhieuBanHang objChiTiet in lstChiTiet)
                        {
                            //kiem tra so luong nhap nho hon so luong ton
                            int soLuongTon = MatHangDao.GetSoLuongTonByDonViTinh(objChiTiet.MaMatHang, obj.MaKho, objChiTiet.MaDonViTinh);
                            if (soLuongTon < objChiTiet.SoLuong)
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                            objChiTiet.MaPhieuBanHang = obj.MaPhieuBanHang;
                            if (!ChiTietPhieuBanHangDao.Insert(objChiTiet))
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                            //Update MatHangTonKho
                            MatHangTonKho objTonKho = new MatHangTonKho();
                            objTonKho.MaDonViTinh = objChiTiet.MaDonViTinh;
                            objTonKho.MaKho = obj.MaKho;
                            objTonKho.MaMatHang = objChiTiet.MaMatHang;
                            objTonKho.SoLuongTon = objChiTiet.SoLuong;
                            if (!MatHangTonKhoDao.RemoveMatHangTonKho(objTonKho))
                            {
                                ManagerDao.Rollback();
                                return false;
                            }
                        }
                        //commit here
                        ManagerDao.Commit();
                        return true;
                    }
                   
                }
                else//Error.
                {
                    ManagerDao.Rollback();
                    return false;
                }

            }
            catch (Exception e)
            {
                //write error Message to log file.
                logger.Error(methodName, e);
                
            }
            ManagerDao.Rollback();
            return false;
        }
        public static Curency GetCurencyForPhieuBanHang(Int64 maPhieuBanHang)
        {
            Curency objResult = null;
            String methodName = "GetCurencyForPhieuBanHang";
            if (logger.IsDebugEnabled)
            {
                LoggingUtility.logMethodEntry(logger, methodName);
            }
            try
            {
               
                DbCommand dbCommnand = ManagerDao.GetStoredProcCommand("spGetCurencyForPhieuBanHang");
                //Add value "MaPhieuBanHang"  paramater.
                ManagerDao.AddInParameter(dbCommnand, "MaPhieuBanHang", DbType.Int64, maPhieuBanHang);
                IDataReader reader = ManagerDao.ExecuteReader(dbCommnand);
                if (reader.Read())
                {
                    objResult = CurencyDao.GetCurencyByDataReader(reader);
                }
                reader.Close();
            }
            catch (System.Exception e)
            {
                //write error message to log file.
                logger.Error(methodName, e);
            }
            return objResult;               
        }
    }
}
        #endregion